import _ from 'lodash'
var player = { obj: null, next: null }
const recorderManager = uni.getRecorderManager()
let requestRecord = false
const imUtils = {
  _p: (cb) => new Promise(cb),
  _filePathToLocal: file => plus.io.convertLocalFileSystemURL(file),
  _filePathPrefix (file) {
      if (['file://', '/'].indexOf(file) === 0) {
          return 'file://' + file.replace('file://', '')
      } else {
          return im._filePathPrefix(plus.io.convertLocalFileSystemURL(file))
      }
  },
  current_user_tag: '',
  queueMaps: {},
  queueWait (waitScope = 'common') {
    imUtils.queueMaps[waitScope] = imUtils.queueMaps[waitScope] || []
    return new Promise(resolve => {
      imUtils.queueMaps[waitScope].push(resolve)
      if (imUtils.queueMaps[waitScope].length === 1) {
        resolve(imUtils.queueNext(waitScope))
      }
    })
  },
  queueNext (waitScope) {
    return () => {
      imUtils.queueMaps[waitScope].shift()
      if (imUtils.queueMaps[waitScope].length > 0) {
        imUtils.queueMaps[waitScope][0](imUtils.queueNext(waitScope))
      }
    }
  },
  MSG_TEXT: 'text',
  MSG_IMAGE: 'image',
  MSG_VIDEO: 'video',
  MSG_TIP_FACE: 'tip_face',
  MSG_AUDIO: 'audio',
  MSG_LOCATION: 'location',
  buildMessageItem () {
    let [type, data, ...payload] = arguments
    return({
      type,
      data,
      payload: imUtils._messageItemPayloadFormat(type, payload)
    })
  },
  _messageItemPayloadFormat (type, payload) {
    let retVal = {}
    switch (type) {
      case imUtils.MSG_VIDEO:
        retVal = {
          videoCover: payload[0],
          ...(payload[1] || {})
        }
        break;
      case imUtils.MSG_AUDIO:
        retVal = {
          timeLength: payload[0],
          ...(payload[1] || {})
        }
        break;
      case imUtils.MSG_LOCATION:
        retVal = {
          lat: payload[0],
          lon: payload[1],
          addr: payload[2],
          ...(payload[3] || {})
        }
        break;
      default:
        retVal = payload[0]
        break;
    }
    return retVal
  },
  playAudio (link, next) {
    console.log(link)
    player.next = next
    player.obj = plus.audio.createPlayer({ src: link, autoplay: true })
    let ending = (e) => {
      console.log(e)
      console.log('touch')
      player.obj.stop()
      player.obj.close()
      next()
    }
    player.obj.addEventListener('ended', ending)
    player.obj.addEventListener('error', ending)
  },
  stopAudio () {
    try {
      if (player.obj) {
        player.obj.stop()
        player.obj.close()
        player.next()
      }
    } catch (e) {

    }
  },
  // 聊天记录工具集
  genStorageKey (key) {
    let retKey = `${imUtils.current_user_tag}_${key}`
    if (key.indexOf(imUtils.current_user_tag) === 0) {
      retKey = key
    }
    return retKey
  },
  getStorageKeys () {
    return uni.getStorageInfoSync().keys
  },
  setStorageByKey (key, value) {
    let realKey = imUtils.genStorageKey(key)
    try {
      value = JSON.stringify(value)
    } catch (e) {

    }
    uni.setStorageSync(realKey, value)
  },
  getStorageByKey (key) {
    let realKey = imUtils.genStorageKey(key)
    let value = uni.getStorageSync(realKey)
    try {
      value = JSON.parse(value)
    } catch (e) {

    }
    return value
  },
  deleteStorageByKey (key) {
    let keys = [].concat(key)
    keys.forEach(k => {
      let realKey = imUtils.genStorageKey(k)
      uni.removeStorageSync(realKey)
    })
  },
  setCurrentUser (tag) {
    imUtils.current_user_tag = tag
  },
  getCurrentUser () {
    return imUtils.current_user_tag
  },
  TALK_PRE_KEY: 'talk_',
  getTalkLogList () {
    let keys = imUtils.getStorageKeys()
    let preset = imUtils.genStorageKey(imUtils.TALK_PRE_KEY)
    keys = keys.filter(key => key.indexOf(preset) === 0)
    let results = []
    keys.forEach(key => {
      results.push(imUtils.getStorageByKey(key))
    })
    results = results.sort((a, b) => {
      return new Date(b.time).getTime() - new Date(a.time).getTime()
    })
    return results
  },
  setTalkLog (userid, nick, head, time, text, count) {
    let Skey = `${imUtils.TALK_PRE_KEY}${userid}`
    let talkLog = imUtils.getStorageByKey(Skey)
    talkLog = talkLog || { userid, nick, head, time, text, count }
    talkLog = {
      ...talkLog,
      userid: !_.isNil(userid) ? userid : talkLog.userid,
      nick: !_.isNil(nick) ? nick : talkLog.nick,
      head: !_.isNil(head) ? head : talkLog.head,
      time: !_.isNil(time) ? time : talkLog.time,
      text: !_.isNil(text) ? text : talkLog.userid,
      count: !_.isNil(count) ? count : talkLog.count,
    }
    imUtils.setStorageByKey(Skey, talkLog)
  },
  delTalkLog (userid) {
    let Skey = imUtils.genStorageKey(`${imUtils.TALK_PRE_KEY}${userid}`)
    imUtils.deleteStorageByKey(Skey)
    imUtils.delMessageLogList(userid)
  },
  MESSAGE_PRE_KEY: 'uMsg_',
  async getMessageLogList (userid, pageIndex, pageSize) {
    let quitQueue = await imUtils.queueWait(`${imUtils.MESSAGE_PRE_KEY}${userid}`)
    let uMsgSkey = imUtils.genStorageKey(`${imUtils.MESSAGE_PRE_KEY}${userid}`)
    let uMsgIndexList = imUtils.getStorageByKey(uMsgSkey) || []
    let results = []
    uMsgIndexList = uMsgIndexList.slice((pageIndex - 1) * pageSize, pageIndex * pageSize)
    uMsgIndexList.forEach(logId => {
      let mLogSkey = imUtils.genStorageKey(`${imUtils.MESSAGE_PRE_KEY}${userid}-${logId}`)
      results.push(imUtils.getStorageByKey(mLogSkey))
    })
    setTimeout(e => {
      quitQueue()
    }, 3000)
    return results
  },
  async delMessageLog (userid, logId) {
    let quitQueue = await imUtils.queueWait(`${imUtils.MESSAGE_PRE_KEY}${userid}`)
    let uMsgSkey = imUtils.genStorageKey(`${imUtils.MESSAGE_PRE_KEY}${userid}`)
    let uMsgIndexList = imUtils.getStorageByKey(uMsgSkey) || []
    let mLogSkey = imUtils.genStorageKey(`${imUtils.MESSAGE_PRE_KEY}${userid}-${logId}`)
    imUtils.deleteStorageByKey(mLogSkey)
    uMsgIndexList = uMsgIndexList.filter(key => key != logId)
    imUtils.setStorageByKey(uMsgSkey, uMsgIndexList)
    setTimeout(e => {
      quitQueue()
    }, 3000)
  },
  async delMessageLogList (userid) {
    let quitQueue = await imUtils.queueWait(`${imUtils.MESSAGE_PRE_KEY}${userid}`)
    let uMsgSkey = imUtils.genStorageKey(`${imUtils.MESSAGE_PRE_KEY}${userid}`)
    let uMsgIndexList = imUtils.getStorageByKey(uMsgSkey) || []
    uMsgIndexList.forEach(index => {
      let mLogSkey = imUtils.genStorageKey(`${imUtils.MESSAGE_PRE_KEY}${userid}-${index}`)
      imUtils.deleteStorageByKey(mLogSkey)
    })
    uMsgIndexList = []
    imUtils.setStorageByKey(uMsgSkey, uMsgIndexList)
    setTimeout(e => {
      quitQueue()
    }, 3000)
  },
  async addMessageLog (userid, data) {
    let quitQueue = await imUtils.queueWait(`${imUtils.MESSAGE_PRE_KEY}${userid}`)
    let uMsgSkey = imUtils.genStorageKey(`${imUtils.MESSAGE_PRE_KEY}${userid}`)
    let uMsgIndexList = imUtils.getStorageByKey(uMsgSkey) || []
    let LogId = uMsgIndexList.length === 0 ? 0 : uMsgIndexList[uMsgIndexList.length - 1] + 1
    let mLogSkey = imUtils.genStorageKey(`${imUtils.MESSAGE_PRE_KEY}${userid}-${LogId}`)
    imUtils.setStorageByKey(mLogSkey, { userid, data, id: LogId })
    uMsgIndexList.push(LogId)
    imUtils.setStorageByKey(uMsgSkey, uMsgIndexList)
    setTimeout(e => {
      quitQueue()
    }, 1000)
    return LogId
  },
  // 触发一次语音权限验证
  touchRecordPermission () {
    requestRecord = true
    if (!requestRecord) {
      recorderManager.start()
      recorderManager.stop()
    }
  },
  // 开始录音
  async startRecord () {
    return imUtils._p(next => {
      recorderManager.onError(e => {
        console.log(e)
        next(false)
      })
      recorderManager.start()
      setTimeout(() => next(true), 1500)
    })
  },
  // 结束录音
  endRecord () {
    return imUtils._p(next => {
      recorderManager.onStop(({ tempFilePath }) => {
        next(tempFilePath)
      })
      recorderManager.onError(e => next(''))
      recorderManager.stop()
      setTimeout(() => next(''), 1000)
    })
  },
  async openAlbumBridge (albumType) {
    return imUtils._p(next => {
      let event_name = 'openAlbumBridge' + new Date().getTime()
      uni.$on(event_name, data => {
        next(data)
      })
      uni.navigateTo({
        url: `/components/ChatAlbumBridge?albumType=${albumType}&event=${event_name}`
      })
    })
  },
  // 相机拍照/录像
  CAMERA_TYPE_TAKE_PHOTO: 1,
  CAMERA_TYPE_RECORD: 2,
  // 获取Tutu实例
  getVideoType (filePath = '') {
    let vSuffixs = ['avi','flv','mpg','mpeg','mpe','m1v','m2v','mpv2','mp2v','dat','ts','tp','tpr','pva','pss','mp4','m4v','m4p','m4b','3gp','3gpp','3g2','3gp2','ogg','mov','qt','amr','rm','ram','rmvb','rpm']
    let isVideo = vSuffixs.find(item => filePath.substr(-item.length) === item)
    return isVideo
  },
  getTutu () {
    return uni.requireNativePlugin("Zhimi-camera")
  },
  async openCamera (cameraType = imUtils.CAMERA_TYPE_TAKE_PHOTO, cameraOption = {}) {
    let tutu = imUtils.getTutu()
    return imUtils._p((next, err) => {
      let fn = {
        [imUtils.CAMERA_TYPE_TAKE_PHOTO]: tutu.takePhoto,
        [imUtils.CAMERA_TYPE_RECORD]: tutu.Picker,
      }[cameraType]
      fn(cameraOption, next)
    })
  },
  // 媒体文件压缩（路径使用原生路径，不需要file://）
  async compressImage (file) {
    let tutu = imUtils.getTutu()
    return imUtils._p((next, err) => {
      // 图片压缩比例 0-1
      tutu.setImageQuality(1, file, res => {
        if (res.code !== 0) {
          err(res)
        }
        next(res)
      });
      // 图片高度，等比例缩放
      // tutu.setImageHeight(100,"filmPath", res =>{
      //   console.log(res);
      // })
    })
  },
  async compressVideo (file) {
    let tutu = imUtils.getTutu()
    return imUtils._p((next, err) => {
      // 视频质量 默认 0 640x480， 1 960x540， 2 1280x720， 3 1920x1080， 4 3840x2160
      tutu.setVideoQuality(0, file, res => {
        if (res.code !== 0) {
          err(res)
        }
        next(res)
      });
    })
  },
  // 获取定位
  async getLocation () {
    return imUtils._p(next => {
      uni.getLocation({
        type: 'gcj02',
        geocode: true,
        success: next,
        complete (e) {
          console.log(e)
          next({  })
        }
      })
    })
  },
  // 选择位置
  async chooseLocation () {
    let { latitude, longitude, address } = await imUtils.getLocation()
    address = Object.values(address || []).join('')
    return imUtils._p(next => {
      uni.chooseLocation({
        latitude,
        longitude,
        keyword: address,
        success: next,
        complete (e) {
          console.log(e)
        }
      })
    })
  },
  async openLocation (latitude, longitude, keyword) {
    uni.openLocation({ latitude, longitude, address: keyword })
  },
  // 高德静态图
  async getLocationImage (latitude, longitude) {
    let locationKey = '2dd51e0fa7727916b3f71d4bc0ee842b'
    return `https://restapi.amap.com/v3/staticmap?location=${longitude},${latitude}&zoom=10&size=200*200&markers=mid,,:${longitude},${latitude}&key=${locationKey}`
  },
  // 下载文件缓存
  async getUrlCachePath (url, path) {
    if (path) {
      uni.setStorageSync(url, path)
    } else {
      return uni.getStorageSync(url, path)
    }
  },
  async hasFile (filePath) {
    return imUtils._p(next => {
      uni.getFileInfo({
        filePath,
        success: e => {
          next(e.size ? e.size : false)
        },
        fail: e => {
          next(false)
        }
      })
    })
  },
  isExsits (filePath) {
    return imUtils._p(next => {
      plus.io.getFileInfo({
        filePath,
        success: next,
        fail: next
      })
    })
  },
  async downloadFile (url) {
    let filePath = await imUtils.getUrlCachePath(url)
    let fileSaved = false
    if (filePath) {
      fileSaved = await imUtils.hasFile(filePath)
    }
    return fileSaved ? filePath : imUtils._p(async next => {
      uni.downloadFile({
        url,
        success: ({ tempFilePath }) => {
          uni.saveFile({
            tempFilePath,
            success: ({ savedFilePath }) => {
              imUtils.getUrlCachePath(url, savedFilePath)
              next(savedFilePath)
            },
            fail (e) {
              console.log(e)
              next(url)
            }
          })
        },
        fail (e) {
          console.log(e)
          next(url)
        }
      })
    })
  }
}
export default imUtils
